//用户登录注册等
/**
 * @openapi
 * tags:
 * - name: user
 *   description: 用户登录相关
 */
const router = require("express-promise-router")();
const ParseHelper = require("../helpers/parse");

const UserService = require("../services/user");
const LogService = require("../services/log");

const {checkTeacherOrAdmin}=require("../auth_checker");
const config = require('../config/config');

/**
 * @openapi
 * /user/reg:
 *   post:
 *     tags:
 *     - user
 *     summary: 用户注册
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               password:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 成功
 *       400:
 *         description: 失败{"error":"..."}
 */
//用户注册
//在v5_user表中注册，然后在Parse中注册相同用户名用户并连接
router.post('/reg', async function(req, res) {
    const loginUser=req.session.user;
    const {username,password,showName,isTeacher}=req.body;
    try{
        const result = await UserService.reg(username,password,showName,isTeacher);
        //console.log('reg result',result);
        LogService.addLog(loginUser,"用户",`}注册`);
        res.status(200).send(result)//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/login:
 *   post:
 *     tags:
 *     - user
 *     summary: 用户登录
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               password_md5:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 成功，返回user，服务端 req.session.user=user
 *       400:
 *         description: 失败 {error:"..."}
 */
//成功登录后把用户放到session中
router.post('/login', async function(req, res) {
    const {username,password_md5}=req.body;
    try{
        const user=await UserService.verifyByPasswordMD5(username,password_md5);
        req.session.user=user;
        delete user.password;//返回前去除密码
        delete user.password_aes;//返回前去除密码
        delete user.password_md5;//返回前去除密码
        delete user.access_token;//返回前去除微信的access_token
        LogService.addLog(user,"登录",`登录成功`);
        res.json(user);//成功 200
    }catch (e) {
        LogService.addLog({username},"登录",`登录失败`);
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/check_password:
 *   post:
 *     tags:
 *     - user
 *     summary: 检查用户名密码
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               password_md5:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 成功，返回user，服务端 req.session.user=user
 *       400:
 *         description: 失败 {error:"..."}
 */
//成功登录后把用户放到session中
router.post('/check_password', async function(req, res) {
    const {username,password_md5}=req.body;
    try{
        const user=await UserService.verifyByPasswordMD5(username,password_md5);
        res.status(200).json(user);//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/wechat_user_login:
 *   post:
 *     tags:
 *     - user
 *     summary: 微信用户登录
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               access_token:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 成功，返回user，服务端 req.session.user=user
 *       400:
 *         description: 失败 {error:"..."}
 */
//成功登录后把用户放到session中
router.post('/wechat_user_login', async function(req, res) {
    const {username,access_token}=req.body;
    try{
        const user=await UserService.verifyByWechatAccessToken(username,access_token);
        req.session.user=user;
        delete user.password;//返回前去除密码
        delete user.password_aes;//返回前去除密码
        delete user.password_md5;//返回前去除密码
        delete user.access_token;//返回前去除微信的access_token
        res.json(user);//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});


/**
 * @openapi
 * /user/xcx_user_login:
 *   post:
 *     tags:
 *     - user
 *     summary: 微信小程序用户登录
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               session_key:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 成功，返回user，服务端 req.session.user=user
 *       400:
 *         description: 失败 {error:"..."}
 */
//成功登录后把用户放到session中
router.post('/xcx_user_login', async function(req, res) {
    const {username,session_key}=req.body;
    try{
        const user=await UserService.verifyByXcxSessionKey(username,session_key);
        req.session.user=user;
        delete user.password;//返回前去除密码
        delete user.password_aes;//返回前去除密码
        delete user.password_md5;//返回前去除密码
        delete user.access_token;//返回前去除微信的access_token
        res.json(user);//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/me:
 *   get:
 *     tags:
 *     - user
 *     summary: 用户信息
 *     responses:
 *       200:
 *         description: 成功
 *       400:
 *         description: 没有登录
 */
//个人信息
router.get('/me', async function(req, res) {
    const user=req.session.user;
    if(!user){
        res.status(400).send("没有登录");
    }else{
        res.json(user);
    }
});


/**
 *
 * @openapi
 * /user/change_password:
 *   post:
 *     tags:
 *     - user
 *     summary: 修改密码
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               old_password:
 *                 type: string
 *               new_password:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 修改成功
 *       400:
 *         description: 失败
 */
//修改密码
router.post('/change_password',async function(req, res) {
    const {username,old_password,new_password}=req.body;
    try{
        await UserService.change_password(username,old_password,new_password);
        LogService.addLog(req.session.user,"用户",`修改密码：${username}`);
        res.end();//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 *
 * @openapi
 * /user/reset_password:
 *   post:
 *     tags:
 *     - user
 *     summary: 重置密码
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 修改成功
 *       400:
 *         description: 失败
 */
//修改密码
router.post('/reset_password',async function(req, res) {
    const {username}=req.body;
    try{
        await UserService.reset_password(username);
        LogService.addLog(req.session.user,"用户",`重置密码:${username}`);
        res.end();//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 *
 * @openapi
 * /user/update_one_field:
 *   post:
 *     tags:
 *     - user
 *     summary: 更新用户信息
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               key:
 *                 type: string
 *               value:
 *                 type: string
 *               id:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 修改成功
 *       400:
 *         description: 失败
 */
//更新用户信息
//这个接口应该只有管理员可以调用
router.post('/update_one_field',checkTeacherOrAdmin,async function(req, res) {
    const {key,value,objectId}=req.body;
    try{
        const result = await UserService.update_one_field(key,value,objectId);
        //console.log('update_one_field result',result);
        LogService.addLog(req.session.user,"用户",`更新信息：${objectId}：${key}=>${value}`);
        res.end();//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/update:
 *   post:
 *     tags:
 *     - user
 *     summary: 更新用户信息
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               key:
 *                 type: string
 *               value:
 *                 type: string
 *               id:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 修改成功
 *       400:
 *         description: 失败
 */
//更新用户信息
//这个接口应该只有管理员可以调用
router.post('/update',async function(req, res) {
    const userObj=req.body;
    try{
        const result = await UserService.update(userObj);
        LogService.addLog( req.session.user,"用户",`更新：${JSON.stringify(userObj)}`);
        res.end();//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/get_username_by_unionid/{unionid}:
 *   get:
 *     tags:
 *     - user
 *     summary: 根据unionid取得用户username
 *     parameters:
 *       - in: path
 *         name: unionid
 *         required: true
 *         schema:
 *           type: string
 *         description: 微信用户的unionid
 *     responses:
 *       200:
 *         description: 修改成功
 *       400:
 *         description: 失败
 */
router.get('/get_username_by_unionid/:unionid', async (req, res) => {
    const unionid=req.params.unionid;
    if(!unionid){
        throw new Error("no unionid");
    }
    const username=await UserService.get_username_by_unionid(unionid);
    console.log('get_username_by_unionid',username);
    if(username){
        res.json(username);
    }else{
        res.status(400).json({"error":"not found user"});
    }
});




/**
 * @openapi
 * /user/update_session_key:
 *   post:
 *     tags:
 *     - user
 *     summary: 更新用户unionid 的session_key，应该只有support平台调用
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               unionid:
 *                 type: string
 *               session_key:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 更新成功
 *       400:
 *         description: 失败
 */
router.post('/update_session_key', async (req, res) => {
    const {unionid,session_key}=req.body;
    try{
        const user=await UserService.update_session_key_by_unionid(session_key,unionid);
        req.session.user=user;
        delete user.password;//返回前去除密码
        delete user.password_aes;//返回前去除密码
        delete user.password_md5;//返回前去除密码
        res.json(user);//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/bind_username_and_unionid:
 *   post:
 *     tags:
 *     - user
 *     summary: 绑定用户名 username 与 unionid ,同时保存 access_token,linkWith到Parse的User表
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               unionid:
 *                 type: string
 *               access_token:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 绑定成功
 *       400:
 *         description: 失败
 */
router.post('/bind_username_and_unionid', async (req, res) => {
    const {username,unionid,access_token}=req.body;
    try{
        const user=await UserService.update_unionid_and_access_token(username,unionid,access_token);
        await UserService.link_user_and_wechat(username,unionid,access_token);//首次绑定的时候必须调用，相当于注册wechat_auth
        req.session.user=user;
        delete user.password;//返回前去除密码
        delete user.password_aes;//返回前去除密码
        delete user.password_md5;//返回前去除密码
        LogService.addLog(user,"用户",`微信绑定用户`);
        res.status(200).send(user);//成功 200
        return;
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
        return;
    }
});

/**
 * @openapi
 * /user/link_user_and_wechat:
 *   post:
 *     tags:
 *     - user
 *     summary: linkWith到Parse的User表
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               unionid:
 *                 type: string
 *               access_token:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 绑定成功
 *       400:
 *         description: 失败
 */
router.post('/link_user_and_wechat', async (req, res) => {
    const {username,unionid,access_token}=req.body;
    try{
       const result = await UserService.link_user_and_wechat(username,unionid,access_token);
        res.status(200).send(result);//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

/**
 * @openapi
 * /user/update:
 *   post:
 *     tags:
 *     - user
 *     summary: 更新用户信息
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               username:
 *                 type: string
 *               value:
 *                 type: string
 *               id:
 *                 type: string
 *       required: true
 *     responses:
 *       200:
 *         description: 修改成功
 *       400:
 *         description: 失败
 */
//用户信息解绑微信
router.post('/unbind_wechat', async (req, res) => {
    const userObj=req.body;
    console.log('userObj',userObj)
    try{
        const result = await UserService.update_one_field('unionid',null,userObj.objectId);
        const jsonObj = ParseHelper.toJSON(result);
        if(jsonObj.unionid==null){
            await UserService.unlink_user_and_wechat(userObj.username);
            //解除支撑平台绑定信息
            await UserService.unbindSupport(userObj.unionid)
        }
        LogService.addLog( req.session.user,"用户",`更新：${JSON.stringify(userObj)}`);
        res.end();//成功 200
    }catch (e) {
        res.status(400).send({error:e.toString()}); //失败 400,返回{error:"..."}
    }
});

//根据输入的部分username获取到符合的用户
router.post('/queryUsersByUsername', async(req, res) => {
    const {partOfUsername} = req.body;
    const users = await UserService.queryUsersByUsername(partOfUsername);
    res.send(users);
});

// 绑卡
router.post('/bind', async (req, res) => {
    const {userId, cardId} = req.body;
    const user = await UserService.bindCard(userId, cardId);
    res.send(user);
});

module.exports = router;
